package com.zero.book.service;

import com.zero.book.entity.Book;
import com.zero.book.message.MessageConstant;

import java.util.*;

import static com.zero.book.constant.DeleteConstant.DELETE_BY_ID;
import static com.zero.book.constant.DeleteConstant.DELETE_BY_TITLE;
import static com.zero.book.constant.ModifyConstant.*;
import static com.zero.book.constant.SearchConstant.*;
import static com.zero.book.message.MessageConstant.*;
import static com.zero.book.message.MessageConstant.INPUT_ERROR;
import static com.zero.book.utils.CatchEnter.*;
import static com.zero.book.utils.PrintUtil.*;
import static com.zero.book.service.SerialService.*;
public class CRUDService {

    /**
     * 存储书籍的数据库
     */
    private static Map<Integer, Book> dataMap = new LinkedHashMap<>();
    

    public static void Entry(Scanner sc) {
        print(INPUT_BOOK_MES);
        //输入异常捕获，统一用nextLine解决
        print(INPUT_BOOK_NAME);
        String title = sc.nextLine();
        print(INPUT_BOOK_AUTHOR);
        String author = sc.nextLine();
        print(INPUT_BOOK_PRICE);
        double price = Double.parseDouble(sc.nextLine());
        //建造者模式
        Book book = Book.builder()
                .title(title)
                .author(author)
                .price(price)
                .build();
        //TODO 检测数值是否为空，做进一步的添加&修改操作
        //从序列获取当前的继续ID值
        int key = SetCurKey();
        dataMap.put(key, book);

        //序列化
        serialSaveService(dataMap);
        print(ADD_BOOK_SUCCESS + ": " + book);
    }
    
    /**
     * 修改功能
     *
     * @param sc sc
     */
    public static void Modify(Scanner sc) {
        //修改功能，可以通过全书名，和 id查询进行修改
        boolean loop = true;
        dataMap = serialLoadService();
        while (loop) {
            print(MODIFY_BOOK_MES);
            print(MODIFY_BY_ID_MES);
            print(MODIFY_BY_TITLE_MES);
            print(EXIT_MODIFY_MES);
            if (!EnterChoice(sc, MODIFY_BY_ID_MES, EXIT_MODIFY_MES)) {
                continue;
            }
            switch (getData()) {
                case MODIFY_BY_ID:
                    print(ENTER_MODIFY_ID);
                    Integer id;
                    try {
                        id = Integer.parseInt(sc.nextLine());
                    } catch (NumberFormatException e) {
                        System.out.println(INPUT_ERROR);
                         continue;
                    }
                    if (dataMap.containsKey(id)) {
                        print(CONDITION_QUERY_MES + "" + dataMap.get(id));
                        print(ACQUIRE_INFO_MES);
                        print(ENTER_BOOK_NAME_MES);
                        String title = sc.nextLine();
                        print(ENTER_BOOK_AUTHOR_MES);
                        String author = sc.nextLine();
                        print(ENTER_BOOK_PRICE_MES);
                        double price = Double.parseDouble(sc.nextLine());
                        Book book = Book.builder()
                                .title(title.isEmpty() ? dataMap.get(id).getTitle() : title)
                                .author(author.isEmpty() ? dataMap.get(id).getAuthor() : author)
                                .price(price)
                                .build();
                        dataMap.put(id, book);
                        //序列化存储，存入修改后的数据
                        serialSaveService(dataMap);
                        //序列化读取,读取修改后的数据
                        dataMap = serialLoadService();
                        printf(MODIFIED_BY_ID + "", id, book);
                    } else {
                        printf(BY_ID_NOT_FOUND + "", id);
                    }
                    break;
                case MODIFY_BY_TITLE:
                    print(ENTER_MODIFY_NAME);
                    String title = sc.nextLine();
                    Set<Map.Entry<Integer, Book>> entries = dataMap.entrySet();
                    boolean existed = false;
                    for (Map.Entry<Integer, Book> entry : entries) {
                        Book entity = entry.getValue();
                        Integer key = entry.getKey();
                        if (entity.getTitle().equals(title)) {
                            print(CONDITION_QUERY_MES + "" + entity);
                            existed = true;
                            print(ACQUIRE_INFO_MES);
                            print(ENTER_BOOK_NAME_MES);
                            String new_title = sc.nextLine();
                            print(ENTER_BOOK_AUTHOR_MES);
                            String author = sc.nextLine();
                            print(ENTER_BOOK_PRICE_MES);
                            double price = Double.parseDouble(sc.nextLine());
                            //实体化修改的对象
                            Book book = Book.builder()
                                    .title(title.isEmpty() ? entity.getTitle() : new_title)
                                    .author(author.isEmpty() ? entity.getAuthor() : author)
                                    .price(price).build();
                            dataMap.put(key, book);
                            serialSaveService(dataMap);
                            dataMap = serialLoadService();
                            printf(MODIFIED_BY_TITLE + "", entity.getTitle(), dataMap.get(key));
                        }
                    }
                    if (!existed) {
                        printf(BY_TITLE_NOT_FOUND + "", title);
                    }
                    break;
                case EXIT_MODIFY:
                    loop = false;
                    break;
                default:
                    print(INPUT_ERROR);
                    break;
            }
        }
    }

    /**
     * 查询功能
     * 根据id查找，书名模糊查询，作者模糊查询，展示所有书籍
     *
     * @param sc sc
     */
    public static void Query(Scanner sc) {
        boolean loop = true;
        //加载序列化，读取数据
        dataMap = serialLoadService();
        while (loop) {
            print(QUERY_BOOK_MES);
            print(QUERY_BY_ID_MES);
            print(QUERY_BLUR_TITLE_MES);
            print(QUERY_BLUR_AUTHOR_MES);
            print(QUERY_ALL_MES);
            print(EXIT_QUERY_MES);

            //创建遍历的iterator，便于模糊查询
            Set<Map.Entry<Integer, Book>> entries = dataMap.entrySet();
            Iterator<Map.Entry<Integer, Book>> iterator = entries.iterator();

            if (!EnterChoice(sc, QUERY_BY_ID_MES, EXIT_QUERY_MES)) {
                continue;
            }
            switch (getData()) {
                case BY_ID:
                    print(ENTER_QUERY_ID);
                    Integer id;
                    try {
                        id = Integer.parseInt(sc.nextLine());
                    } catch (NumberFormatException e) {
                        System.out.println(INPUT_ERROR);
                        continue;
                    }
                    if (dataMap.containsKey(id)) {
                        printf(ACQUIRED_BY_ID + "", id, dataMap.get(id));
                    } else {
                        printf(NOT_FOUND_BY_ID + "", id);
                    }
                    break;
                case BY_TITLE:
                    print(ENTER_QUERY_NAME);
                    String rex_title = sc.nextLine();
                    boolean exist_name = false;
                    while (iterator.hasNext()) {
                        Book entry = iterator.next().getValue();
                        if (entry.getTitle().contains(rex_title)) {
                            exist_name = true;
                            print(CONDITION_QUERY_MES + "" + entry);
                        }
                    }
                    if (!exist_name) {
                        printf(BY_TITLE_NOT_FOUND + "", rex_title);
                    }
                    break;
                case BY_AUTHOR:
                    print(ENTER_QUERY_AUTHOR);
                    String rex_auth = sc.nextLine();
                    boolean exist_author = false;
                    while (iterator.hasNext()) {
                        Book entry = iterator.next().getValue();
                        if (entry.getAuthor().contains(rex_auth)) {
                            exist_author = true;
                            print(CONDITION_QUERY_MES + "" + entry);
                        }
                    }
                    if (!exist_author) {
                        printf(NOT_FOUND_BY_AUTHOR + "", rex_auth);
                    }
                    break;
                case ALL:
                    print(QUERY_ALL_SHOW_MES);
                    dataMap = serialLoadService();
                    IteratorDataMap(dataMap);
                    break;
                case QUERY_EXIT:
                    loop = false;
                    break;
                default:
                    print(INPUT_ERROR);
                    break;
            }
        }
    }

    public static void Delete(Scanner sc) {
        //删除功能，可以通过id删除，和书名删除
        boolean loop = true;
        dataMap = serialLoadService();
        while (loop) {
            print(DELETE_BOOK_MES);
            print(DELETE_BY_ID_MES);
            print(DELETE_BY_TITLE_MES);
            print(EXIT_DELETE_MES);
            if (!EnterChoice(sc, DELETE_BY_ID_MES, EXIT_DELETE_MES)) {
                continue;
            }
            switch (getData()) {
                case DELETE_BY_ID:
                    print(ENTER_DELETE_ID);
                    Integer id;
                    try {
                        id = Integer.parseInt(sc.nextLine());
                    } catch (NumberFormatException e) {
                        System.out.println(INPUT_ERROR);
                        continue;
                    }
                    if (dataMap.containsKey(id)) {
                        print(OPERATION_DELETE_MES + "" + dataMap.remove(id));
                        //序列化存储，存入修改后的数据
                        serialSaveService(dataMap);
                        //序列化读取,读取修改后的数据
                        dataMap = serialLoadService();
                        printf(DELETE_SHOW_BY_ID_MES + "", id);
                        print(AFTER_DELETED);
                        IteratorDataMap(dataMap);
                    } else {
                        printf(BY_ID_NOT_FOUND + "", id);
                    }
                    break;
                case DELETE_BY_TITLE:
                    print(ENTER_DELETE_NAME);
                    String title = sc.nextLine();
                    Set<Map.Entry<Integer, Book>> entries = dataMap.entrySet();
                    boolean removed = false;
                    for (Map.Entry<Integer, Book> entry : entries) {
                        Book entity = entry.getValue();
                        Integer key = entry.getKey();
                        if (entity.getTitle().equals(title)) {
                            print(OPERATION_DELETE_MES + "" + dataMap.remove(key));
                            removed = true;
                            serialSaveService(dataMap);
                            dataMap = serialLoadService();
                            printf(DELETE_SHOW_BY_TITLE_MES + "", title);
                            print(AFTER_DELETED);
                            //优化遍历，重复代码
                            IteratorDataMap(dataMap);
                        }
                    }
                    if (!removed) {
                        printf(BY_TITLE_NOT_FOUND + "", title);
                    }
                    break;
                case EXIT_MODIFY:
                    loop = false;
                    break;
                default:
                    print(INPUT_ERROR);
                    break;
            }
        }
    }

    /**
     * 设置当前的数值id
     *
     * @return int
     */
    static int SetCurKey(MessageConstant... tips) {
        int key = 0;
        Map<Integer, Book> dataMap = serialLoadService(tips);
        Set<Map.Entry<Integer, Book>> entries = dataMap.entrySet();
        Iterator<Map.Entry<Integer, Book>> iterator = entries.iterator();
        //当数据为空时
        if (dataMap.isEmpty()) {
            return 1;
        }
        while (iterator.hasNext()) {
            Map.Entry<Integer, Book> entry = iterator.next();
            if (entry.getKey() > key) {
                key = entry.getKey();
            }
        }
        return key + 1;
    }

    /**
     * 迭代器数据映射
     *
     * @param map 地图
     */
    private static <K, V> void IteratorDataMap(Map<K, V> map) {
        map.forEach((k, v) -> print(k + ":" + v));
    }
}
